﻿#include "RegExpViewDo.h"
#include <qsciscintilla.h>
#include <Scintilla.h>
#include <QMainWindow>
#include <QRegExp>
#include <QMessageBox>
#include <QTextCodec>
typedef sptr_t(*SCINTILLA_FUNC) (sptr_t ptr, unsigned int, uptr_t, sptr_t);
typedef sptr_t SCINTILLA_PTR;

#pragma execution_character_set("utf-8")
SCINTILLA_FUNC m_pScintillaFunc;
SCINTILLA_PTR  m_pScintillaPtr;


RegExpViewtClass::RegExpViewtClass(QWidget *parent, QsciScintilla* pEdit)
	: QWidget(parent)
{
	ui.setupUi(this);
	m_pEdit = pEdit;
	mainWidget_ = parent;
	m_pScintillaFunc = (SCINTILLA_FUNC)m_pEdit->SendScintillaPtrResult(SCI_GETDIRECTFUNCTION);
	m_pScintillaPtr = (SCINTILLA_PTR)m_pEdit->SendScintillaPtrResult(SCI_GETDIRECTPOINTER);
}

RegExpViewtClass::~RegExpViewtClass()
{}

QString RegExpViewtClass::unicode2utf8(QString unicode)
{

	QString result;
	int index = unicode.indexOf("\\u");	//设置解码的起始位置
	while (index != -1 && index < unicode.length())
	{

		QString flag = unicode.mid(index, 2);//用于检测下一个字符是否为unicode
		if (flag == "\\u")	//对每一个unicode编码进行处理
		{
			QString s1 = unicode.mid(index + 2, 4);
			result.append(s1.toUShort(0, 16));
			index += 6;		//每个unicode编码的字符形式都为\u****的形式，为防止出现错误与重复，在检测完毕后建议将指针后移6位
		}
		else if (flag == "\"}")	//设置解码的终止位置
		{
			break;
		}
		else	//剩下一种情况为非unicode的状态的字符，一般为符号、字母和数字
		{
			QString s2 = unicode.mid(index, 1);
			result.append(s2);
			index += 1;	//为防止出现遗漏，在每个非unicode的状态的字符检测后，将指针只移动一位
		}
	}
	return result;
}
sptr_t execute(quint32 Msg, uptr_t wParam = 0, sptr_t lParam = 0) {
	try {
		return (m_pScintillaFunc) ? m_pScintillaFunc(m_pScintillaPtr, Msg, wParam, lParam) : -1;
	}
	catch (...)
	{
		return -1;
	}
};

void RegExpViewtClass::on_upper()
{
	int colorIndex = 1;
	int rpos = 0, pos = 0;
	QStringList ResultOut;
	m_pEdit = scintillaCallback_();
	m_pScintillaFunc = (SCINTILLA_FUNC)m_pEdit->SendScintillaPtrResult(SCI_GETDIRECTFUNCTION);
	m_pScintillaPtr = (SCINTILLA_PTR)m_pEdit->SendScintillaPtrResult(SCI_GETDIRECTPOINTER);

	QString RegExpViewText = ui.lineEdit_1->text();
	if (ui.lineEdit_1->text().length() == 0)
		return;

	QRegExp replaceFx("\\\\u[0-9a-fA-F]+");
	QString  GetUnicodeText = RegExpViewText;
	while ((rpos = replaceFx.indexIn(RegExpViewText, rpos)) != -1) //若存在unicode字符，对unicode 字符进行处理
	{
		rpos += replaceFx.matchedLength();
		GetUnicodeText.replace(replaceFx.cap(0), unicode2utf8(replaceFx.cap(0)));
	}

	QRegExp findx(GetUnicodeText);

	QString text = m_pEdit->text();
	int totalLength = m_pEdit->SendScintilla(SCI_GETLENGTH);

	for (int i = 0; i < 2; ++i)
	{
		execute(SCI_SETINDICATORCURRENT, 21 + i);
		if (lastTotalLength > totalLength)
		{
			execute(SCI_INDICATORCLEARRANGE, 0, lastTotalLength);//确保清除所有标记
		}
		else
		{
			execute(SCI_INDICATORCLEARRANGE, 0, totalLength);
		}
	}
	lastTotalLength = totalLength;
	while ((pos = findx.indexIn(text, pos)) != -1)
	{
		pos += findx.matchedLength();
		ResultOut.append(findx.cap(0));//保存正则表达式匹配结果
	}
	int startpos = 0;
	int endpos = totalLength;
	m_pEdit->SendScintilla(SCI_SETTARGETSTART, -1);//设置查找范围
	m_pEdit->SendScintilla(SCI_SETTARGETEND, totalLength);
	for each (QString var in ResultOut)
	{
		std::string str = var.toStdString();//对中文进行处理
		const char* ch = str.c_str();

		int res = m_pEdit->SendScintilla(SCI_SEARCHINTARGET, strlen(ch), ch);//返回查找到的位置

		if (res >= 0)
		{
			execute(SCI_SETINDICATORCURRENT, 21 + (++colorIndex % 2));
			execute(SCI_INDICATORFILLRANGE, res, strlen(ch));
			startpos = var.toLocal8Bit().length() + res;
		}
		else
		{
			startpos += var.toLocal8Bit().length();//若出现错误,直接跳过
		}
		m_pEdit->SendScintilla(SCI_SETTARGETSTART, startpos);
		m_pEdit->SendScintilla(SCI_SETTARGETEND, totalLength);
	}
}
void RegExpViewtClass::setScintilla(const std::function<QsciScintilla* ()>& cb)
{
	scintillaCallback_ = cb;
}
